package controller

import (
	"fmt"
	"iptv_server/v3/src/settings"
	"iptv_server/v3/src/source_manager"
	"iptv_server/v3/v2_src/utils/cache"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
)

var (
	r            *gin.Engine
	NotFoundJson = gin.H{
		"code": -1,
	}

	cache30min *cache.Cache[string]
)

func init() {
	r = gin.Default()
	r.Use(cors.Default())
}

func Run(addr ...string) {
	r.Run(addr...)
}

func New_V3Handlers() http.Handler {

	cache30min = cache.NewCache[string]("cache30 minCache", time.Minute*time.Duration(30)) // 30 min

	//router
	r.StaticFS(settings.UrlPath_StaticFile, http.Dir(settings.Dir_StaticFile))
	r.GET("/tv/home/:key", handleHome)
	r.GET("/tv/category/:id/:pg/:key", handlecategory)
	r.GET("/tv/detail/:id/:key", handleDetail) // sourcekey
	r.GET("/tv/detail_more/:group/:middle/:name", handleMoreDetail)
	r.GET("/tv/play/:id/:key", handlePlay) // 暂时不需要这个了!

	r.GET("/tv/clearcache", func(c *gin.Context) {
		cache30min.Clear()
	})

	r.GET("/api.json", func(c *gin.Context) {
		fmt.Printf("c.Request.URL.Path: %v\n", c.Request.URL.Path)
		c.Redirect(http.StatusMovedPermanently, settings.PATH_API_JSON)
	})

	r.GET("/favicon.ico", func(c *gin.Context) {
		//fmt.Printf("c.Request.URL.Path: %v\n", c.Request.URL.Path)
		lower := strings.ToLower(c.Request.Host)
		if strings.Contains(lower, "tv") {
			c.Redirect(http.StatusMovedPermanently, settings.FAVICON_TV)
		} else {
			c.Redirect(http.StatusMovedPermanently, settings.FAVICON)
		}
	})

	mux := New_V2Handlers()

	r.Any("/api/*path", func(c *gin.Context) {
		fmt.Printf("c.Request.URL.Path: %v\n", c.Request.URL.Path)
		mux.ServeHTTP(c.Writer, c.Request)
	})

	initOthers(r)

	return r.Handler()

}

// func PrintResponse(c *gin.Context) {
// 	now := time.Now()
// 	// 先执行handler下面中间件和handler
// 	c.Next()

// 	fmt.Printf("this is response, cost: %d",
// 		time.Since(now).Nanoseconds())
// }

func handleHome(ctx *gin.Context) {
	m := source_manager.GetSourceManager(ctx.Param("key"))
	if m == nil {
		ctx.JSON(200, NotFoundJson)
		return
	}
	h, err := m.GetHome(ctx.Param("id"))
	// h, err := homevideo_model.GetHome(1)
	if err != nil {
		fmt.Printf("err: %v\n", err)
		ctx.JSON(200, NotFoundJson)
		return
	}
	// h.Type = 2 //1=list , 2=cover
	fmt.Printf("h: %v\n", h)
	ctx.JSON(200, h)

	// ctx.JSON(200, cl)
}

const (
	limit int = 20 // count for every page
)

func handlecategory(ctx *gin.Context) {
	if handleMoreCate(ctx) {
		return
	}

	m := source_manager.GetSourceManager(ctx.Param("key"))
	if m == nil {
		ctx.JSON(200, NotFoundJson)
		return
	}
	id := ctx.Param("id")
	pg := ctx.Param("pg")

	data, err := m.GetPage(id, strconv.Itoa(limit), pg)
	// str_id := ctx.Param("id")
	// str_page := ctx.Param("pg") //page
	// id, err := strconv.ParseUint(str_id, 10, 0)
	// if err != nil || id < 1 {
	// 	id = 1
	// }

	// page, err := strconv.ParseInt(str_page, 10, 0)
	// if err != nil || page < 1 {
	// 	page = 1
	// }

	// data, err := homevideo_model.GetPage(uint(id), limit, int(page))
	if err != nil || data == nil {
		ctx.JSON(200, NotFoundJson)
		return
	}

	// fmt.Printf("data: %v\n", data.Details)

	ctx.JSON(200, data)
}

func handleDetail(ctx *gin.Context) {

	m := source_manager.GetSourceManager(ctx.Param("key"))
	if m == nil {
		ctx.JSON(200, NotFoundJson)
		return
	}

	data, err := m.GetDetail(ctx.Param("id"))
	// str_id := ctx.Param("id")
	// sourcekey :=
	// id, err := strconv.ParseUint(str_id, 10, 0)
	if err != nil || data == nil {
		ctx.JSON(200, NotFoundJson)
		return
	}
	ctx.JSON(200, data)

	// if err == nil && id > 1 {
	// 	data, err := homevideo_model.GetDetail(uint(id))
	// 	if err == nil {
	// 		v := convertDetailPlayListToString(data)
	// 		ctx.JSON(200, v)
	// 		return
	// 	}
	// }

}

func handlePlay(ctx *gin.Context) {
	m := source_manager.GetSourceManager(ctx.Param("key"))
	if m == nil {
		ctx.JSON(200, NotFoundJson)
		return
	}
	data, err := m.GetPlay(ctx.Param("id"))
	if err != nil || data == nil {
		ctx.JSON(200, NotFoundJson)
		return
	}
	ctx.JSON(200, data)

	// str_id :=
	// id, err := strconv.ParseUint(str_id, 10, 0)
	// if err == nil && id > 1 {
	// 	data, err := homevideo_model.GetPlay(uint(id))
	// 	if err == nil {
	// 		ctx.JSON(200, data)
	// 		return
	// 	}
	// }
	// ctx.JSON(200, NotFoundJson)
}
